package com.tools.common.container;

import com.tools.common.container.r.OnlyReadHashMap;
import com.tools.common.container.r.OnlyReadLinkedMap;
import com.tools.common.container.r.OnlyReadTreeMap;
import com.tools.common.object.Note;

import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.Set;

/**
 * 自定义 Map 键值对包装容器接口
 * */
@Note("自定义 Map 键值对包装容器接口")
public interface OwnPairs<K, V> {

    /* *******************************************************************************************
     *
     *          增删方法
     *
     * *******************************************************************************************
     * */

    @Note("添加一个 key-value 键值对")
    OwnPairs<K, V> put(K key, V value);

    @Note("如果 sourceKey 不存在则添加 backupValue")
    OwnPairs<K, V> putIfAbsent(K sourceKey, V backupValue);

    @Note("把 Map 集合里的所有 key-value 添加到容器中")
    OwnPairs<K,V> putAll(Map<? extends K, ? extends V> map);

    @Note("把目标自定义键值对容器里的所有 key-value 添加到容器中")
    OwnPairs<K,V> putAll(OwnPairs<? extends K, ? extends V> pair);

    @Note("移除指定的 key")
    OwnPairs<K,V> remove(Object key);

    @Note("移除指定数组内所有匹配到的 key")
    OwnPairs<K,V> removeAll(Object[] keys);

    @Note("移除指定 Collection 集合内所有匹配到的 key")
    OwnPairs<K,V> removeAll(Collection<?> keys);

    @Note("移除指定自定义容器集合内所有匹配到的 key")
    OwnPairs<K,V> removeAll(OwnRows<?> keys);

    @Note("移除指定可迭代容器内所有匹配到的 key")
    OwnPairs<K,V> removeAll(Iterable<?> keys);

    @Note("移除指定的 key-value")
    OwnPairs<K,V> remove(K key, V value);

    @Note("移除 Map 集合里所有匹配到的 key-value")
    OwnPairs<K,V> removeAll(Map<? extends K, ? extends V> map);

    @Note("移除可迭代容器里所有匹配到的 key-value")
    OwnPairs<K,V> removeAll(OwnPairs<? extends K, ? extends V> pair);

    /* *******************************************************************************************
     *
     *          获取查询方法
     *
     * *******************************************************************************************
     * */

    @Note("根据 key 获取 value")
    V get(Object key);

    @Note("如果 key 不存在则返回 defaultValue")
    V getOrDefault(Object key, V defaultValue);

    @Note("判断容器内是否存在指定的 key")
    boolean containsKey(K key);

    @Note("判断数组内的所有 key 是否都存在于容器中")
    boolean containsAllKey(K[] keys);

    @Note("判断 Collection 集合内的所有 key 是否都存在于容器中")
    boolean containsAllKey(Collection<? extends K> keys);

    @Note("判断自定义容器集合内的所有 key 是否都存在于容器中")
    boolean containsAllKey(OwnRows<? extends K> keys);

    @Note("判断可迭代容器内的所有 key 是否都存在于容器中")
    boolean containsAllKey(Iterable<? extends K> keys);

    @Note("判断容器中是否存在任意一个数组中存储的 key")
    boolean containsAnyKey(K[] keys);

    @Note("判断 Collection 集合中是否存在任意一个目标可迭代容器中存储的 key")
    boolean containsAnyKey(Collection<? extends K> keys);

    @Note("判断自定义容器集合中是否存在任意一个目标可迭代容器中存储的 key")
    boolean containsAnyKey(OwnRows<? extends K> keys);

    @Note("判断可迭代容器中是否存在任意一个目标可迭代容器中存储的 key")
    boolean containsAnyKey(Iterable<? extends K> keys);

    @Note("判断容器内是否存在指定的 value")
    boolean containsValue(V value);

    @Note("判断数组内的所有 value 是否都存在于容器中")
    boolean containsAllValue(V[] values);

    @Note("判断 Collection 集合内的所有 value 是否都存在于容器中")
    boolean containsAllValue(Collection<? extends V> values);

    @Note("判断自定义容器集合内的所有 value 是否都存在于容器中")
    boolean containsAllValue(OwnRows<? extends V> values);

    @Note("判断可迭代容器内的所有 value 是否都存在于容器中")
    boolean containsAllValue(Iterable<? extends V> values);

    @Note("判断容器中是否存在任意一个数组中存储的 value")
    boolean containsAnyValue(V[] values);

    @Note("判断 Collection 集合中是否存在任意一个目标可迭代容器中存储的 value")
    boolean containsAnyValue(Collection<? extends V> values);

    @Note("判断自定义容器集合中是否存在任意一个目标可迭代容器中存储的 value")
    boolean containsAnyValue(OwnRows<? extends V> values);

    @Note("判断容器中是否存在任意一个目标可迭代容器中存储的 value")
    boolean containsAnyValue(Iterable<? extends V> values);

    /* *******************************************************************************************
     *
     *          通用方法
     *
     * *******************************************************************************************
     * */

    @Note("返回键值对集合中的元素个数")
    int size();

    @Note("判断容器是否为空")
    boolean isEmpty();

    @Note("返回键值对集合中的键值对条目的 Set 集合")
    Set<Map.Entry<K, V>> entrySet();

    @Note("返回键值对集合中的 key 的 Set 集合")
    Set<K> keySet();

    @Note("判断内部封装的键值对容器是否已经初始化了（即不为 null）")
    boolean initialized();

    @Note("获取所有 value 的 Collection 集合")
    Collection<V> values();

    @Note("清空容器的所有数据")
    void clear();

    @Note("获取容器的实现类枚举")
    MapEnum getImplEnum();

    @Note("获取容器的排序比较器")
    Comparator<? super K> getComparator();

    @Note("把容器转为 Map 集合")
    Map<K,V> toMap();

    @Note("把容器转为 Map 集合，具体 Map 集合的实现类由 MapEnum 枚举值决定")
    Map<K,V> toMap(MapEnum implEnum);

    @Note("复制容器的内容到目标 Map 集合里")
    void copyTo(Map<K, V> map);

    @Note("将容器转为只读的 HashMap 集合")
    OnlyReadHashMap<K, V> toOnlyReadHashMap();

    @Note("将容器转为只读的 LinkedHashMap 集合")
    OnlyReadLinkedMap<K, V> toOnlyReadLinkedMap();

    @Note("将容器转为只读的 TreeMap 集合")
    OnlyReadTreeMap<K, V> toOnlyReadTreeMap();

    @Note("将容器转为只读的 TreeMap 集合，并指定排序规则")
    OnlyReadTreeMap<K, V> toOnlyReadTreeMap(Comparator<? super K> comparator);
}
